import os
import threading
import json
from typing import Any


class GlobalConfigs:
    _instance_lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if not hasattr(GlobalConfigs, "_instance"):
            with GlobalConfigs._instance_lock:
                if not hasattr(GlobalConfigs, "_instance"):
                    GlobalConfigs._instance = object.__new__(cls)
        return GlobalConfigs._instance

    def __init__(self, env):
        self._data = None
        self.env = env
        self._base_dir = None
        self._config_dir = None
        self._resource_dir = None
        self._log_dir = None
        self.__set_dir()
        self._load_static_config()

    @property
    def data(self):
        return self._data

    @property
    def log_dir(self):
        return self._log_dir

    @property
    def resource_dir(self):
        return self._resource_dir

    @property
    def base_dir(self):
        return self._base_dir

    @property
    def config_dir(self):
        return self._config_dir

    def _load_static_config(self):
        path = None
        if os.path.exists(os.path.join(os.path.dirname(__file__), "config_%s.json" % self.env)):

            path = os.path.join(os.path.dirname(__file__), "config_%s.json" % self.env)
        else:
            path = os.path.join(os.path.dirname(__file__), "config.json")

        with open(path, 'rb') as f:
            data = f.read()
            self._data = json.loads(data)

    def add_config(self, category: str, config: dict):
        if not self._data.get(category):
            self._data[category] = dict()
        self._data[category].update(config)

    def get_config(self, category: str, key: Any, default=None):
        if self._data.get(category):
            self._data.get(category).get(key, default)
        else:
            return default

    def __set_dir(self):
        self._config_dir = os.path.dirname(__file__)
        self._base_dir = os.path.dirname(self._config_dir)
        self._resource_dir = os.path.join(self._base_dir, "resource")
        self._log_dir = os.path.join(self._base_dir, 'log')

    def reload_config(self, env=""):
        self.env = env
        self._load_static_config()


configs = GlobalConfigs(env="dev")
